package com.kelvin.backend.redis.service.lock;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.kelvin.backend.redis.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * <p>Title: AbstractBaseLockService</p>
 * <p>Description: </p>
 *
 * @author Kelvin.Chen
 * @datetime 2021/10/21 7:27
 */
@Component
public abstract class AbstractBaseLockService implements BaseLockService {

    protected Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    protected RedisService redisService;

    @Override
    public void lock(String key, Object value, long second) {
        while (!redisService.setIfAbsent(key, value, second)) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.error("出现异常 -> {}", ExceptionUtil.stacktraceToOneLineString(e));
                Thread.currentThread().interrupt();
            }
        }
    }

    @Override
    public void unlock(String key) {
        Object value = redisService.get(key);
        if (ObjectUtil.isNotEmpty(value)) {
            redisService.remove(key);
        }
    }

    @Override
    public void execute(String key, Object value, long second, InterfaceLockService service) {
        try {
            lock(key, value, second);
            service.execute();
        } finally {
            unlock(key);
        }
    }

}
